# # Karlsruher Institut fuer Technologie # Institut fuer Anthropomatik und Robotik (IAR) # Vorlesung Rechnerorganisation # # Autor: James Bond # Matrikelnummer: 007 # Tutoriumsnummer: 42 # Name des Tutors: TI # .data # The playing board is represented in the form field[row][column] # Each array entry is either 0 (no piece) or 1/2 (piece by player 1/2) board: .space 42 prompt: .asciiz "Bitte Spalte eingeben (1-7): " player1_turn: .asciiz "Spieler 1 ist am Zug!\n" player2_turn: .asciiz "Spieler 2 ist am Zug!\n" symb_empty: .asciiz "[ ] " symb_player1: .asciiz "[X] " symb_player2: .asciiz "[O] " fin_won1: .asciiz "Spieler 1 hat gewonnen!\n" fin_won2: .asciiz "Spieler 2 hat gewonnen!\n" fin_draw: .asciiz "Spiel ist unentschieden!\n" newline: .asciiz "\n" .text .globl main # Initialize game main: move $s0, $ra jal clear_board li $s1, 1 # $s0 := active player m_loop: # Print board jal print_board move $a0, $s1 jal print_player # Prompt for move m_loop_inp: jal read_move move $a0, $v0 move $a1, $s1 jal drop_piece bnez $v0, m_loop_inp # Switch to other player li $t0, 3 sub $s1, $t0, $s1 # Has the game ended? jal check_fin beqz $v0, m_loop # Print game result and exit move $a0, $v0 jal print_result move $ra, $s0 jr $ra ### # clear_board: Clears the board # Parameters: - # Return values: - ### clear_board: # Loop over memory containing board and set all fields to zero li $t0, 0 clear_b_l: sb $zero, board($t0) addi $t0, $t0, 1 blt $t0, 42, clear_b_l jr $ra ### # print_player: Prints the current active player # Parameters: $a0: Player number # Return values: - ### print_player: # Load correct string for output beq $a0, 2, p_player_2 la $a0, player1_turn j p_player_p p_player_2: la $a0, player2_turn # Output string p_player_p: li $v0, 4 syscall jr $ra ### # print_board: Prints the current state of the board # Parameters: - # Return values: - ### print_board: # Note: $s2 - $s4 is not used in main, therefore no backup is needed move $s2, $ra # Print newline la $a0, newline li $v0, 4 syscall # Outer loop: Loop over rows li $s3, 0 # Inner loop: Loop over columns print_b_l1: li $s4, 0 print_b_l2: move $a0, $s3 move $a1, $s4 # Check board state at position and load correct string for output jal peek beq $v0, 1, print_b_p1 beq $v0, 2, print_b_p2 la $a0, symb_empty j print_b_p print_b_p1: la $a0, symb_player1 j print_b_p print_b_p2: la $a0, symb_player2 # Output string print_b_p: li $v0, 4 syscall # Advance to next column addi $s4, $s4, 1 ble $s4, 6, print_b_l2 # Advance to next row la $a0, newline li $v0, 4 syscall addi $s3, $s3, 1 ble $s3, 5, print_b_l1 move $ra, $s2 jr $ra ### # print_result: Prints the result of a finished game. # Parameters: $a0: 1 or 2 if the corresponding player has won, 3 otherwise (draw). # Return values: - ### print_result: # Select correct string for output beq $a0, 2, p_result_2 beq $a0, 3, p_result_3 la $a0, fin_won1 j p_result_p p_result_2: la $a0, fin_won2 j p_result_p p_result_3: la $a0, fin_draw # Output string p_result_p: li $v0, 4 syscall jr $ra ### # read_move: Asks user for move and checks input for validity # Parameters: - # Return values: $v0: Column to drop piece in (zero-based, 0-6) ### read_move: # Print prompt li $v0, 4 la $a0, prompt syscall # Read int and check for valid range li $v0, 5 syscall blez $v0, read_move bgt $v0, 7, read_move # Decrement column to get zero-based number addi $v0, $v0, -1 jr $ra ### # peek: Check the board state at the given coordinates. # Parameters: $a0: Row, $a1: Column # Return values: $v0: Number of the player that has a piece at the position, or zero. ### peek: # Calculate array address li $t0, 7 mul $t0, $a0, $t0 add $t0, $t0, $a1 # Make memory access and return value lb $v0, board($t0) jr $ra ### # drop_piece: Drops a piece for the given player in the column. # Parameters: $a0: Column, $a1: Player number # Return values: $v0: 0 if the move is valid and has been executed, 1 otherwise. ### drop_piece: # Note: $s2 - $s5 are not used in main, therefore no backup is needed move $s2, $ra move $s3, $a0 move $s4, $a1 # Check whether the move is legal move $a1, $a0 li $a0, 0 jal peek bnez $v0, drop_p_err # Find free position in column for piece li $s5, 6 drop_p_l: addi $s5, $s5, -1 move $a0, $s5 move $a1, $s3 jal peek bnez $v0, drop_p_l # Store player number in field li $t0, 7 mul $t0, $s5, $t0 add $t0, $t0, $s3 sb $s4, board($t0) # Report success li $v0, 0 j drop_p_end drop_p_err: li $v0, 1 drop_p_end: move $ra, $s2 jr $ra ### # check_fin: Checks whether the game is finished, i.e. there is a winner or a draw. # Parameters: - # Return values: $v0: 1 or 2 if the corresponding player has won, 3 if draw, 0 otherwise. ### check_fin: # Note: $s2 - $s5 are not used in main, therefore no backup is needed move $s2, $ra # Check for draw li $a0, 0 li $a1, 0 c_fin_cd: jal peek beqz $v0, c_fin_nd addi $a1, $a1, 1 blt $a1, 7, c_fin_cd # Report a draw li $v0, 3 j c_fin_end # Now, this won't win a prize for efficiency (check players separately) c_fin_nd: li $s3, 1 # Check for win by four horizontal pieces c_fin_pl: move $a2, $s3 li $s4, 0 c_fin_h1: li $s5, 0 c_fin_h2: move $a0, $s4 move $a1, $s5 jal check_horiz bnez $v0, c_fin_end addi $s5, $s5, 1 ble $s5, 3, c_fin_h2 addi $s4, $s4, 1 ble $s4, 5, c_fin_h1 # Check for win by four vertical pieces move $a2, $s3 li $s4, 0 c_fin_v1: li $s5, 0 c_fin_v2: move $a0, $s4 move $a1, $s5 jal check_vert bnez $v0, c_fin_end addi $s5, $s5, 1 ble $a1, 6, c_fin_v2 addi $s4, $s4, 1 ble $s4, 2, c_fin_v1 # Check for win by four diagonal pieces (top-left to bottom-right) move $a2, $s3 li $s4, 0 c_fin_d11: li $s5, 0 c_fin_d12: move $a0, $s4 move $a1, $s5 jal check_diag1 bnez $v0, c_fin_end addi $s5, $s5, 1 ble $s5, 3, c_fin_d12 addi $s4, $s4, 1 ble $s4, 2, c_fin_d11 # Check for win by four diagonal pieces (top-right to bottom-left) move $a2, $s3 li $s4, 0 c_fin_d21: li $s5, 3 c_fin_d22: move $a0, $s4 move $a1, $s5 jal check_diag2 bnez $v0, c_fin_end addi $s5, $s5, 1 ble $s5, 6, c_fin_d22 addi $s4, $s4, 1 ble $s4, 2, c_fin_d21 addi $s3, $s3, 1 beq $s3, 2, c_fin_pl # No draw and no player has won li $v0, 0 c_fin_end: move $ra, $s2 jr $ra ### # check_horiz: Checks for win by four horizontal pieces, starting at the given position. # Parameters: $a0: Row, $a1: Column, $a2: Player number to check for # Return values: $v0: Number of the player if he has won, otherwise zero. ### check_horiz: # Note: $s6-$s7 not used in main or check_fin, therefore no backup is needed move $s6, $ra # Check four adjacent fields li $s7, 0 c_horiz_l: jal peek bne $v0, $a2, c_horiz_nw addi $s7, $s7, 1 addi $a1, $a1, 1 blt $s7, 4, c_horiz_l # Player has won! move $v0, $a2 j c_horiz_e # Player has not won c_horiz_nw: li $v0, 0 c_horiz_e: move $ra, $s6 jr $ra ### # check_vert: Checks for win by four vertical pieces, starting at the given position. # Parameters: $a0: Row, $a1: Column, $a2: Player number to check for # Return values: $v0: Number of the player if he has won, otherwise zero. ### check_vert: # Note: $s6-$s7 not used in main or check_fin, therefore no backup is needed move $s6, $ra # Check four adjacent fields li $s7, 0 c_vert_l: jal peek bne $v0, $a2, c_vert_nw addi $s7, $s7, 1 addi $a0, $a0, 1 blt $s7, 4, c_vert_l # Player has won! move $v0, $a2 j c_vert_e # Player has not won c_vert_nw: li $v0, 0 c_vert_e: move $ra, $s6 jr $ra ### # check_diag1: Checks for win by four diagonal pieces (top-left to bottom-right), # starting at the given position. # Parameters: $a0: Row, $a1: Column, $a2: Player number to check for # Return values: $v0: Number of the player if he has won, otherwise zero. ### check_diag1: # Note: $s6-$s7 not used in main or check_fin, therefore no backup is needed move $s6, $ra # Check four adjacent fields li $s7, 0 c_diag1_l: jal peek bne $v0, $a2, c_diag1_nw addi $s7, $s7, 1 addi $a0, $a0, 1 addi $a1, $a1, 1 blt $s7, 4, c_diag1_l # Player has won! move $v0, $a2 j c_diag1_e # Player has not won c_diag1_nw: li $v0, 0 c_diag1_e: move $ra, $s6 jr $ra ### # check_diag2: Checks for win by four diagonal pieces (top-right to bottom-left), # starting at the given position. # Parameters: $a0: Row, $a1: Column, $a2: Player number to check for # Return values: $v0: Number of the player if he has won, otherwise zero. ### check_diag2: # Note: $s6-$s7 not used in main or check_fin, therefore no backup is needed move $s6, $ra # Check four adjacent fields li $s7, 0 c_diag2_l: jal peek bne $v0, $a2, c_diag2_nw addi $s7, $s7, 1 addi $a0, $a0, 1 addi $a1, $a1, -1 blt $s7, 4, c_diag2_l # Player has won! move $v0, $a2 j c_diag2_e # Player has not won c_diag2_nw: li $v0, 0 c_diag2_e: move $ra, $s6 jr $ra